package org.semanticflash.rdf.io
{
	
	
	import com.bigflexlib.utils.AsyncRunner;
	
	import org.semanticflash.rdf.triple.RDFTriple;
	import org.semanticflash.rdf.values.IRI;
	import org.semanticflash.rdf.values.RDFValue;
	
	
	
	/**
	 * 
	 * Concrete parsers extend this class.
	 * Take a look at RDFXMLParser for a working example
	 * 
	 * @see org.semanticflash.rdf.io.rdfxml.RDFXMLParser
	 * 
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */	
	public class AbstractRDFParser
	{
		
		
		
		
		///////////////////////////////////////////////
		// input
		///////////////////////////////////////////////		
		
		private var _input:*;
		
		public function get input( ):*
		{
			return _input;		
		}
		
		
		
		
		////////////////////////////////////////////////
		// baseURL
		////////////////////////////////////////////////
		
		private var _baseURL:String;
		
		public function get baseURL( ):String
		{
			return _baseURL;
		}
		
		
		
		protected var baseIRI:IRI;
		
		
		
		
		
		
		///////////////////////////////////////////////
		// rdfHandler
		///////////////////////////////////////////////

		private var _rdfHandler:IRDFHandler;
		public function get rdfHandler( ):IRDFHandler
		{
			return _rdfHandler;
		}
		
		
		
		
		
		///////////////////////////////////////////////
		// runner
		///////////////////////////////////////////////		
		
		private var _runner:AsyncRunner;
		public function get runner( ):AsyncRunner
		{
			return _runner;
		}
		



		private var bNodeContext:IRI;




		public function AbstractRDFParser( input:*, rdfHandler:IRDFHandler, baseURL:String = null ):void
		{

			_input 			= input;
			_baseURL 		= baseURL;
			_rdfHandler 	= rdfHandler;
			
			
			// TODO: resolve base URL
			
			baseIRI = IRI.instance( baseURL );
			
			
			bNodeContext = IRI.bNode( );
			
			
			_runner = AsyncRunner.create( $start );

		}
		
		
		
		private function $start( ):void
		{
			AsyncRunner.queue( rdfHandler.startRDF );
			AsyncRunner.queue( start );
		}
		
		
		
		
		
		/**
		 * 
		 * Concrete parsers override this function to plug in their logic
		 * 
		 * @param
		 * 
		 */	
		 protected function start( ):void
		 {
			

		 }
		 
		 
		 
		 
		 /**
		  * 
		  * We should be able to specify a way to avoid processing objects
		  * 
		  * @param s
		  * @param p
		  * @return 
		  * 
		  */		 
		 protected function shouldSkip( s:IRI=null, p:IRI=null, o:IRI=null ):Boolean
		 {
		 
		 	return false;
		 
		 }
		 
		 
		 
		 protected function getBNode( localID:String=null ):IRI
		 {
		 	return IRI.bNode( bNodeContext, localID );
		 }
		 
		 
		 
		 
		 
		 /**
		  * 
		  * Concrete parsers call this method when their work is over
		  * 
		  * 
		  */		 
		 protected function end( ):void
		 {
		 	
		 	rdfHandler.endRDF( );
		 
		 }
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 
		 /**
		 * 
		 * 
		 * 
		 * @param subject
		 * @param predicate
		 * @param object
		 * 
		 */
		protected function assertStatement( subject:RDFValue, predicate:IRI, object:RDFValue ):void
		{
			
//			if ( Log.isDebug( ) )
//			{
//				log.debug( StringUtil.substitute( "assertStatement( {0}, {1}, {2} )", subject, predicate, object) );
//			}
			
			rdfHandler.handleTriple( RDFTriple.instance( subject, predicate, object ) );
			
		}	
		
	}
}